#[cfg(test)]
#[allow(unused)]
mod tests {
    use std::{
        any::{Any, type_name},
        cell::OnceCell,
        collections::HashMap,
        future::Future,
        process::Output,
        str::FromStr,
        sync::{Arc, OnceLock},
    };

    use glass::{
        AsyncCallable, AsyncFunctionWrapper, AsyncRetFn0, Callable, FunctionMeta, Input, Object,
        Reflect, RetAsyncFn, RetFn0, SyncFunctionWrapper, TypeInfo, TypeKind, Value, VariantSerde,
    };
    use glass_core::error::InvokeError;
    use moss::from_meta::{FromMeta, Marker};
    use proc_macro2::TokenStream;
    use serde::{Deserialize, Serialize};
    use syn::{Attribute, DeriveInput, parse_quote};

    #[test]
    fn test_derive() {
        /// aaa
        #[derive(Reflect, Serialize, Deserialize)]
        struct Student<T> {
            #[serde(skip)]
            pub name: String,

            #[serde(rename = "age1")]
            pub age: i32,

            pub teacher: T,
        }

        let map: HashMap<&'static str, FunctionMeta> = HashMap::new();

        #[derive(Reflect)]
        enum Sex {
            Man,
            Woman,
        }

        #[derive(Debug, FromMeta)]
        pub struct Serde {
            pub skip: Option<Marker>,
            pub rename: Option<String>,
        }
    }

    #[test]
    fn test_expand() {
        let mut input: DeriveInput = parse_quote! {
            pub struct Model {
                pub id: u32,

                pub user_id: u32,

                pub real_name: Option<String>,

                pub appellation: Option<String>,

                #[reflect(skip(None))]
                pub custom_field: Option<Json>,
            }
        };

        let result = glass_expand::reflect_derive::expand(&mut input);
        println!("{}", result.unwrap());
    }

    #[test]
    fn test_expand_unit_struct() {
        let mut input: DeriveInput = parse_quote! {
            struct Student;
        };

        let result = glass_expand::reflect_derive::expand(&mut input);
        println!("{}", result.unwrap());
    }

    #[test]
    fn test_expand_enum() {
        enum Sex {
            Man,
            Woman,
        }

        impl TryFrom<glass::Value> for Sex {
            type Error = glass::ConvertError;
            fn try_from(value: Value) -> Result<Self, Self::Error> {
                if let glass::Value::Enum(variant, value) = value {
                    let value = *value;
                    match variant.as_str() {
                        "Woman" => {
                            if let glass::Value::UnitStruct = value {
                                return Ok(Self::Woman);
                            }
                            Err(glass::ConvertError::TypeMismatch {
                                expected: "UnitStruct".into(),
                                actual: value.to_string(),
                            })
                        }
                        _ => Err(glass::ConvertError::NotExistVariant(variant)),
                    }
                } else {
                    Err(glass::ConvertError::TypeMismatch {
                        expected: String::from("Enum"),
                        actual: value.to_string(),
                    })
                }
            }
        }
        impl TryInto<glass::Object> for Sex {
            type Error = glass::ConvertError;
            fn try_into(self) -> Result<glass::Object, Self::Error> {
                match self {
                    Self::Man => Ok(glass::Object {
                        type_info_fn: Self::type_info,
                        value: glass::Value::Enum(
                            String::from("Man"),
                            Box::new(glass::Value::UnitStruct),
                        ),
                    }),
                    Self::Woman => Ok(glass::Object {
                        type_info_fn: Self::type_info,
                        value: glass::Value::Enum(
                            String::from("Woman"),
                            Box::new(glass::Value::UnitStruct),
                        ),
                    }),
                }
            }
        }
        impl glass::Reflect for Sex {
            fn docs() -> Option<String> {
                None
            }
            fn attrs() -> Vec<String> {
                vec!["# [derive (Reflect)]".into()]
            }
            fn kind() -> glass::TypeKind {
                glass::TypeKind::Enum(vec![])
            }
            fn members() -> glass::Members {
                glass::Members::Variants(vec![])
            }
        }

        let mut input: DeriveInput = parse_quote! {
            #[derive(Reflect)]
            enum Sex {
                Man,
                Woman,
            }
        };
        let result = glass_expand::reflect_derive::expand(&mut input);
        println!("{}", result.unwrap());
    }

    #[test]
    fn test_function() {
        #[derive(Debug, Reflect)]
        pub struct Req {
            pub name: String,
        }

        #[derive(Debug, Reflect)]
        pub struct Res {
            pub id: i32,
        }

        pub struct DbConn;

        pub struct UserApi {
            pub db: Arc<DbConn>,
        }

        impl UserApi {
            pub fn get_user(&self, req: Req) -> Res {
                println!("get user");
                Res { id: 1 }
            }
        }

        fn func(mut value: Vec<Object>) -> Result<Option<Object>, InvokeError> {
            let v1 = value.pop().unwrap();
            let req = Req {
                name: "".to_string(),
            };
            let s = UserApi {
                db: Arc::new(DbConn),
            };
            let oneself = v1.value;
            let oneself = match oneself {
                Value::Any(any) => any,
                _ => todo!(),
            };
            let s = oneself.downcast::<UserApi>().unwrap();
            let s = *s;

            UserApi::get_user(&s, req);

            let res = Res { id: todo!() };
            let result = Object {
                type_info_fn: Res::type_info,
                value: Value::Any(Box::new(res)),
            };
            Ok(Some(result))
        }

        pub fn f() {}

        pub struct A;
        impl A {
            pub async fn af() {}
        }

        impl TryFrom<glass::Value> for UserApi {
            type Error = glass::ConvertError;

            fn try_from(value: Value) -> Result<Self, Self::Error> {
                todo!()
            }
        }

        impl TryInto<Object> for UserApi {
            type Error = glass::ConvertError;

            fn try_into(self) -> Result<Object, Self::Error> {
                todo!()
            }
        }

        impl Reflect for UserApi {
            fn functions() -> Vec<FunctionMeta> {
                let af = A::af;
                let af: RetAsyncFn<_, _> = AsyncRetFn0::<(), _>::new(af);
                // vec![FunctionMeta {
                //     trait_name: None,
                //     ident: "get_user".to_owned(),
                //     inputs: vec![Input {
                //         name: todo!(),
                //         ty: todo!(),
                //     }],
                //     output: None,
                //     function: Function::new(&(f as RetFn0)),
                //     async_function: AsyncFunction::new(&(af.func)),
                //     docs: None,
                //     attrs: vec![],
                // }]
                vec![]
            }
        }
        let user_api = UserApi {
            db: Arc::new(DbConn),
        };
        let user_api = Box::new(user_api);
        let user_api = Value::I32(23);
        let user_api = Box::new(user_api);
        let value = Object {
            type_info_fn: todo!(),
            value: todo!(),
        };
        func(vec![value]);
    }
}
